<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义事件</title>
    <script src="./../vue/vue.js"></script>
</head>
<body>
    <!-- 
        事件
            1、 事件名的命名规范 
                使用 短线间隔法 命名 ，因为 v-on 会将DOM中的事件名转化为全小写。而触发事件的名称又是严格匹配，所以无法正确匹配。所以推荐 始终使用 短线间隔法 命名事件名
            2、自定义组件的 v-model 
                v-model             默认 会利用名为 value 的属性和 input 的事件
                model 属性可以 自定义 v-model 绑定的属性名 以及 事件名
                    model: {
                        prop: 'propName',
                        event: 'evnetName'
                    } 
            3、将组件上的事件直接绑定到原生标签上 （使用组件时会将组件上的事件 直接 绑定到原生标签上）
                $listeners 
                （案例中有 $emit $attrs $listeners $event）
            
            4、.sync 修饰符
                组件外部 v-bind:propName.sync = ""
                组件内部 $emit("update:propName", value)

     -->
    <div id="app">

        <div>

            <custom-div @over-five-times.once="onClickButtonOverFiveTimes" :times.sync = "times"></custom-div>
        </div>

        <!-- 自定义input的v-mode绑定 -->
        <div>
            <div>{{ inputValue }}</div>
            <custom-input id="test" v-model="inputValue"></custom-input>
        </div>


        <!-- 自定义 v-mode 的绑定事件 -->
        <div>
            <div>{{ selfDefineValue }}</div>
            <custom-input-self v-model="selfDefineValue"></custom-input-self>
        </div>

        <div>
            <div>base-input: {{ baseValue }}</div>
            <base-input v-model="baseValue" @input="onBaseInputEvent" @focus="getFocus" @blur="onBlur" placeholder="这是自定义input组件"></base-input>
        </div>

    </div>
    
    <script>

        // 组件命名规范
        Vue.component("custom-div",{
            props: ["times"],
            data: function(){
                return {
                    // times: 0
                }
            },
            template: `
            <div>
                <div>私有按钮组件点击次数{{ times }}</div>
                <input type="button" value="点击" @click="onClickButton">
            </div>
            `,
            methods: {
                onClickButton(){
                    
                    // 这种方式实现双向绑定 
                    this.$emit("update:times",this.times + 1)

                    // this.times++
                    if(this.times>5){
                        this.$emit("over-five-times")
                    }
                }
            }
        })
        // 
        Vue.component("custom-input",{
            props:{
                id:{
                    type: String,
                    required: true      // 这里id 被要求必须传递
                },
                value: {
                    type: String
                }
            },
            template: `
            <div>
                <label :for="id">自定义组件</label>
                <input type="text" :id="id" @input="$emit('input',$event.target.value)">
            </div>
            `
        })

        // 自定义组件的v-model 
        Vue.component("custom-input-self",{
            props: ["inputValues"],
            model: {
                prop: 'inputValues',
                event: 'input-action'
            },
            template: `
            <div>
                <label >自定义v-model 的属性和 事件</label>
                <input type="text" @input="$emit('input-action',$event.target.value)" :value="inputValues">
            </div>
            `
        })


        // $listeners
        Vue.component("base-input",{
            inheritAttrs: false,// 移除继承属性的特性
            props: ["value","place"],
            computed: {
                listenersEvents: function(){
                    let that = this
                    return Object.assign({},this.$listeners,{
                        input: function(event){
                            that.$emit('input',event.target.value)
                        }
                    })
                }
            },
            template: `
            <div>
                <input type="text" v-on="listenersEvents" :placeholder="$attrs.placeholder">
            </div>
            `
        })

        let vm = new Vue({
            el: "#app",
            data: {
                times: 0,
                inputValue: null,
                selfDefineValue: null,
                baseValue: null
            },
            methods: {
                onClickButtonOverFiveTimes(){
                    alert("按钮点击超过5次了")
                },

                onBaseInputEvent(event){
                    console.log("event",event)
                },

                getFocus(){
                    console.warn("获得焦点")    
                },

                onBlur(){
                    console.warn("失去焦点")
                }
            },
        })
    </script>

</body>
</html>